<template>
  <transition :name="transitionName" @after-enter="$emit('opened')" @after-leave="$emit('closed')">
    <div
      v-show="value"
      class="popup-box"
      :style="{ animationDuration: transitionDuration }"
      :class="[`popup-${position}`, { round }, `popup-close-${closeIconPosition}`, title || $slots.header ? 'has-title' : '', bgClass]"
      @click="clickPopupSelf($event)"
    >
      <template v-if="title || $slots.header">
        <slot v-if="$slots.header" name="header"></slot>
        <div v-else class="popup-header" :class="[`${titleClass}`]">{{ title }}</div>
        <div class="popup-body" :class="[`${bodyClass}`]">
          <slot v-if="showSlot"></slot>
        </div>
      </template>
      <template v-else>
        <slot v-if="showSlot"></slot>
      </template>
      <slot name="footer"></slot>
      <i v-if="closeable" class="popup-close-icon iconfont" @click="close" :style="closeIconStyle" :class="[`close-${closeIconPosition}`, closeIcon]"></i>
    </div>
  </transition>
</template>
<script>
import touchMixins from './touch';
import overlayManager from './overlay/overlay-manager';
import overlayProps from './overlay/overlayProps';
export default {
  name: 'cj-popup',
  mixins: [touchMixins],
  props: {
    ...overlayProps,
    title: {
      type: String,
      default: ''
    },
    id: {
      type: [String, Number],
      default: ''
    },
    position: {
      type: String,
      default: 'center'
    },
    destroyOnClose: {
      type: Boolean,
      default: false
    },
    round: {
      type: Boolean,
      default: false
    },
    closeable: {
      type: Boolean,
      default: false
    },
    closeIconPosition: {
      type: String,
      default: 'top-right'
    },
    closeIcon: {
      type: String,
      default: 'icon-guanbi'
    },
    closeIconStyle: {
      type: Object,
      default: () => {}
    },
    titleClass: {
      type: String,
      default: ''
    },
    bodyClass: {
      type: String,
      default: ''
    },
    bgClass: {
      type: String,
      default: 'popup-default-bg'
    },
    transition: String,
    getContainer: String
  },
  data() {
    return {
      showSlot: true,
      transitionName: 'popup-fade-center'
    };
  },
  created() {
    this.transition ? (this.transitionName = this.transition) : (this.transitionName = `popup-slide-${this.position}`);
  },
  mounted() {
    if (this.value) {
      this.open();
    }
    this.portal();
  },
  watch: {
    value(val) {
      const type = val ? 'open' : 'close';
      this[type]();
    },
    getContainer: 'portal'
  },
  computed: {
    transitionDuration() {
      return this.duration ? this.duration + 's' : 'initial';
    }
  },
  beforeDestroy() {
    if (this.value) {
      this.close();
    }
  },
  activated() {
    if (this._keepAlive) {
      this.$emit('input', true);
      this._keepAlive = false;
    }
    console.log('activated', this.keepAlive);
  },
  deactivated() {
    if (this.value) {
      this.close();
      this._keepAlive = true;
    }
    console.log('deactivated', this.keepAlive);
  },
  methods: {
    open() {
      if (this._opened) return;
      if (this.destroyOnClose) {
        this.showSlot = true;
      }
      this._opened = true;
      this.$emit('open');
      const { duration, overlayClass, overlayStyle, lockScroll, closeOnClickOverlay } = this;
      const config = {
        zIndex: this.zIndex ? this.zIndex : overlayManager.getZIndex(this.id),
        duration,
        overlayClass,
        overlayStyle,
        lockScroll,
        closeOnClickOverlay
      };
      this.renderOverlay(config);

      if (this.lockScroll) {
        document.addEventListener('touchstart', this.touchStart, false);
        document.addEventListener('touchmove', this.onTouchMove, false);
        if (!overlayManager.lockCount) {
          document.body.classList.add('cj-overflow-hidden');
        }
        overlayManager.lockCount++;
      }
      this.$el.style.zIndex = this.zIndex ? this.zIndex + 1 : overlayManager.getZIndex();
    },
    close() {
      if (!this._opened) return;
      this.$emit('close');
      this._opened = false;
      if (this.lockScroll) {
        overlayManager.lockCount--;
        document.removeEventListener('touchstart', this.touchStart);
        document.removeEventListener('touchmove', this.onTouchMove);
        if (!overlayManager.lockCount) {
          document.body.classList.remove('cj-overflow-hidden');
        }
      }
      if (this.destroyOnClose) {
        setTimeout(() => {
          this.showSlot = false;
        }, this.duration * 1000);
      }
      overlayManager.closeOverlay(this);
      this.$emit('input', false);
    },
    renderOverlay(config) {
      if (!this.value) return;
      if (this.overlay) {
        overlayManager.openOverlay(this, config);
      } else {
        overlayManager.closeOverlay(this);
      }
    },
    portal() {
      const { getContainer } = this;
      if (getContainer) {
        let el = this.$el;
        let container = document.querySelector(getContainer);
        if (container && container !== el.parentNode) {
          container.appendChild(el);
        }
      }
    },
    onTouchMove(event) {
      this.touchMove(event);
      const el = this.getScroller(event.target);
      const { scrollHeight, offsetHeight, scrollTop } = el ? el : this.$el;
      //   console.log(scrollHeight, offsetHeight, scrollTop);
      // console.log(this.deltaY)
      if ((this.deltaY > 0 && scrollTop === 0) || (this.deltaY < 0 && scrollTop + offsetHeight >= scrollHeight)) {
        if (event.cancelable) {
          //事件是否可以取消
          event.preventDefault();
        }
      }
    },
    getScroller(el) {
      let node = el;
      while (node && node.tagName !== 'HTML' && node.nodeType === 1) {
        const { overflowY } = window.getComputedStyle(node);
        if (/scroll|auto/i.test(overflowY)) {
          return node;
        }

        node = node.parentNode;
      }
    },
    clickPopupSelf(e) {
      this.$emit('click', { vm: this, e: e });
    }
  }
};
</script>
